home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Mac Game Programming Gurus
/
TricksOfTheMacGameProgrammingGurus.iso
/
More Source
/
Pascal
/
Book Demos in Pascal
/
ScoresDemo
/
ScoresDemo.p
< prev
next >
Wrap
Text File
|
1995-05-26
|
7KB
|
266 lines
program ScoresDemo;
uses
{$ifc UNDEFINED THINK_PASCAL}
Types, QuickDraw, Events, Windows, Dialogs, Fonts, DiskInit, TextEdit, Traps,{}
Memory, SegLoad, Scrap, ToolUtils, OSUtils, Menus, Resources, StandardFile, {}
GestaltEqu, Files, Errors, Packages, OSEvents,
{$endc}
Preferences;
{***************** A dialog asking for the player's name *****************}
{Filter function for AskHigh, ok = 1 and cancel = 2}
function Filter (theDialog: DialogPtr; var theEvent: EventRecord; var itemHit: integer): Boolean;
var
theChar: Char;
kind: integer;
item: Handle;
box: Rect;
begin
case theEvent.what of
keyDown:
begin
theChar := Char(BitAnd(theEvent.message, charCodeMask));
if ((BitAnd(theEvent.modifiers, cmdkey) <> 0) and (theChar = '.')) or (theChar = char(27)) then {cmd-. or ESC}
begin
itemHit := 2;
{Highlight the cancel button}
GetDItem(theDialog, 2, kind, item, box);
HiliteControl(ControlHandle(item), 1);
Filter := true;
exit(Filter);
end;
if (theChar = char(13)) or (theChar = char(3)) then
begin
itemHit := 1;
{Highlight the OK button}
GetDItem(theDialog, 1, kind, item, box);
HiliteControl(ControlHandle(item), 1);
Filter := true;
exit(Filter);
end;
end; {keyDown}
updateEvt:
begin
BeginUpdate(theDialog);
SetPort(theDialog);
DrawDialog(theDialog);
{Frame default button - item 1}
GetDItem(theDialog, 1, kind, item, box);
InsetRect(box, -4, -4);
PenSize(3, 3);
FrameRoundRect(box, 15, 15);
EndUpdate(theDialog);
end; {update event}
end; {case}
Filter := false;
end; {Filter}
const
kHighDlogRes = 128;
{ Ask for players name (at highscore) }
function AskHigh: str255;
var
dialog: DialogPtr;
oldPort: GrafPtr;
itemHit: integer;
itemHandle: Handle;
itemType: integer;
itemRect: Rect;
str: str255;
begin
GetPort(oldPort);
dialog := GetNewDialog(kHighDlogRes, nil, WindowPtr(-1));
ShowWindow(dialog);
SelectWindow(dialog);
SetPort(dialog);
GetDItem(dialog, 3, itemType, itemHandle, itemRect);
SetIText(itemHandle, 'Your name here'); {Insert string from the prefs file here}
SelIText(dialog, 3, 0, 32767);
itemHit := -1;
while (itemHit <> 1) and (itemHit <> 2) do { 1=ok, 2=cancel }
ModalDialog(@Filter, itemHit);
if itemHit = 2 then
begin
AskHigh := '';
end;
if itemHit = 1 then
begin
GetDItem(dialog, 3, itemType, itemHandle, itemRect);
GetIText(itemHandle, str);
AskHigh := str;
end;
CloseDialog(dialog);
SetPort(oldPort);
end; {AskHigh}
{***************** High score handling *****************}
const
kNameLength = 15;
var
gLastHigh: Integer;
{ Highscore record }
type
HighScoreRec = record
score: array[0..10] of Longint;
name: array[0..10] of string[kNameLength];
end;
HighScorePtr = ^HighScoreRec;
HighScoreHnd = ^HighScorePtr;
var
highScores: HighScoreHnd;
{ Call this on game over! }
procedure UpdateHighScore (score: Longint);
var
num, len: integer;
name, s: str255;
begin
if score > highScores^^.score[10] then
begin
num := 10;
name := AskHigh; {Call some function that asks for the name.}
{Max 15 characters! We take some extra trouble to append '…' too.}
if length(name) > kNameLength then
name := Concat(Copy(name, 1, kNameLength - 1), '…');
if name = '' then { alt length(name) = 0 }
exit(UpdateHighScore);
while (highScores^^.score[num - 1] < score) and (num > 1) do
begin
highScores^^.score[num] := highScores^^.score[num - 1];
highScores^^.name[num] := highScores^^.name[num - 1];
num := num - 1;
end;
gLastHigh := num; {Remember last high for the highscore display}
highScores^^.score[num] := score;
highScores^^.name[num] := name; {AskHigh;}
ChangedResource(Handle(highScores));
end;
end;
{InitScores}
{This procedure loads the high score list from a resource in the current resource file,}
{creating a new one if there is none.}
procedure InitScores;
var
i: integer;
ignoreErr: OSErr;
begin
highScores := HighScoreHnd(GetResource('Bäst', 0));
if highScores = nil then {Didn't exist - create it!}
begin
highScores := HighScoreHnd(NewHandle(Sizeof(HighScoreRec)));
if highScores = nil then
ExitToShell; {Insert error message here}
for i := 1 to 10 do
begin
highScores^^.score[i] := 0;
highScores^^.name[i] := 'Nobody';
end;
highScores^^.score[0] := 10000; { Lowscore }
AddResource(Handle(highScores), 'Bäst', 0, 'High scores');
end
else {Did exist - check the size!}
if GetHandleSize(Handle(highScores)) < sizeof(HighScoreRec) then
SetHandleSize(Handle(highScores), sizeof(HighScoreRec));
end; {InitScores}
(* Standard inits *)
procedure InitToolbox;
begin
{$IFC UNDEFINED THINK_PASCAL}
InitGraf(@qd.thePort);
InitFonts;
FlushEvents(everyEvent, 0);
InitWindows;
InitMenus;
TEInit;
InitDialogs(nil);
{$ENDC}
InitCursor;
end;
{***************** Main program *****************}
var
myWindow: WindowPtr;
str: Str255;
windowRectangle: Rect;
i: Integer;
gAppFile, gPrefFile: integer;
begin
InitToolBox;
{Get the prefs file - create as necessary.}
if SetPrefFile('ScoresDemo Preferences', '????', 'pref', gAppFile, gPrefFile) then
;
{Set the current resource file to the preference file before InitScores}
if gPrefFile <> 0 then
UseResFile(gPrefFile);
InitScores;
UseResFile(gAppFile);
{Let's seed the random number generator so we don't get the same all the time!}
{$ifc UNDEFINED THINK_PASCAL}
qd.randSeed := TickCount;
{$elsec}
randSeed := TickCount;
{$endc}
{Update the high score list with a random score.}
UpdateHighScore(abs(Random));
{Set up the window}
SetRect(windowRectangle, 100, 100, 400, 260);
myWindow := NewCWindow(nil, windowRectangle, 'High scores demo', true, 0, WindowPtr(-1), false, 0);
SetPort(myWindow);
for i := 1 to 10 do
begin
{We draw the latest high score with red.}
if i = gLastHigh then
ForeColor(redColor)
else
ForeColor(blackColor);
{Draw the position number}
MoveTo(10, 15 * i);
NumToString(i, str);
DrawString(str);
{Draw the name}
MoveTo(50, 15 * i);
DrawString(highScores^^.name[i]);
{Draw the score}
MoveTo(200, 15 * i);
NumToString(highScores^^.score[i], str);
DrawString(str);
end;
while not Button do
;
end. {ScoresDemo}